package bs

import net.liftweb._
import http._
import util._
import Helpers._
import scala.xml.{Text, NodeSeq}
import net.liftweb.common.{Full, Empty, Box}

class Button(val text: String) extends LiftComponent {
  val style = collection.mutable.Buffer("btn")
  var iconName: Box[Either[String, String]] = Empty
  var whiteIcon = false

  def primary: this.type = {
    style += "btn-primary"
    this
  }

  def info: this.type = {
    style += "btn-info"
    this
  }

  def success: this.type = {
    style += "btn-success"
    this
  }

  def warning: this.type = {
    style += "btn-warning"
    this
  }

  def danger: this.type = {
    style += "btn-danger"
    this
  }

  def large: this.type = {
    style += "btn-large"
    this
  }

  def small: this.type = {
    style += "btn-small"
    this
  }

  def mini: this.type = {
    style += "btn-mini"
    this
  }

  def inverse: this.type = {
    style += "btn-inverse"
    this
  }

  def block: this.type = {
    style += "btn-block"
    this
  }

  def active: this.type = {
    style += "active"
    this
  }

  def disabled: this.type = {
    style += "disabled"
    this
  }

  def leftIcon(name: String): this.type = {
    iconName = Full(Left(name))
    this
  }

  def leftWhiteIcon(name: String): this.type = {
    whiteIcon = true
    leftIcon(name)
  }

  def rightIcon(name: String): this.type = {
    iconName = Full(Right(name))
    this
  }

  def rightWhiteIcon(name: String): this.type = {
    whiteIcon = true
    rightIcon(name)
  }

  override def transformer: NodeSeq => NodeSeq = {
    val addIconSelector = iconName.map {
      case Left(name) => ("* >*", s"icon-$name")
      case Right(name) => ("* *<", s"icon-$name")
    }

    val writeText = "* *<" #> s" $text "
    val classModifier = "* [class+]" #> style.mkString(" ")

    val addIcon = addIconSelector.map { case (selector, iconNameClass) =>
      val iconClasses = iconNameClass + (if (whiteIcon) " icon-white" else "")
      selector #> <i class={iconClasses}></i>
    }

    import code.lib.ExtCssSel._
    writeText & classModifier &? addIcon
  }

  val template: NodeSeq = <a href="#"></a>
}

class ButtonDropdown(override val text: String, val menu: DropdownMenu) extends Button(text) {
  override val template: NodeSeq = Templates("templates-hidden" :: "bs" :: "_button_dropdown" :: Nil).get

  override def transformer = "a" #> super.transformer &
    "a *<" #> <span class="caret"></span> &
    ".dropdown-menu" #> menu.render
}

object ButtonDropdown {
  def apply(text: String, menu: DropdownMenu) = new ButtonDropdown(text, menu)
}

class ButtonDropup(override val text: String, override val menu: DropdownMenu) extends ButtonDropdown(text, menu) {
  override def transformer = super.transformer & ".btn-group [class+]" #> "dropup"
}

object ButtonDropup {
  def apply(text: String, menu: DropdownMenu) = new ButtonDropup(text, menu)
}

class SplitButtonDropdown(override val text: String, val menu: DropdownMenu) extends Button(text) {
  override val template: NodeSeq = Templates("templates-hidden" :: "bs" :: "_split_button_dropdown" :: Nil).get

  override def transformer = ".btn" #> super.transformer &
    ".dropdown-toggle *" #> <span class="caret"></span> &
    ".dropdown-menu" #> menu.render
}

object SplitButtonDropdown {
  def apply(text: String, menu: DropdownMenu) = new SplitButtonDropdown(text, menu)
}

case class SplitButtonDropup(override val text: String, override val menu: DropdownMenu) extends SplitButtonDropdown(text, menu) {

  override def transformer = super.transformer &
    ".btn-group [class+]" #> "dropup"
}

object Button {
  //  implicit def asTransformer(btn: Button): NodeSeq => NodeSeq = btn.transformer
  def apply(text: String) = new Button(text)
}



